home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / misc / gms_pictures.lha / Pictures / PIC_Init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-22  |  12.6 KB  |  430 lines

  1.  
  2. #include <proto/dpkernel.h>
  3. #include <system/all.h>
  4. #include <dpkernel/prefs.h>
  5. #include "defs.h"
  6.  
  7. /************************************************************************************
  8. ** Action: CheckFile()
  9. ** Object: Picture
  10. */
  11.  
  12. LIBFUNC LONG PIC_CheckFile(mreg(__a0) struct File *File, mreg(__a1) LONG *Buffer)
  13. {
  14.   if (Buffer[0] IS CODE_FORM AND Buffer[2] IS CODE_ILBM) {
  15.      DPrintF("2CheckFile:","File identified as a Picture");
  16.      return(99);
  17.   }
  18.   else {
  19.      return(NULL);
  20.   }
  21. }
  22.  
  23. /************************************************************************************
  24. ** Action: Free()
  25. ** Object: Picture
  26. */
  27.  
  28. LIBFUNC void PIC_Free(mreg(__a0) struct Picture *pic)
  29. {
  30.   if (pic->prvData)    FreeMemBlock(pic->prvData);
  31.   if (pic->prvPalette) FreeMemBlock(pic->prvPalette);
  32.   if (pic->Bitmap)     Free(pic->Bitmap);
  33.   Public->OpenCount--;
  34. }
  35.  
  36. /************************************************************************************
  37. ** Action: Get()
  38. ** Object: Picture
  39. */
  40.  
  41. LIBFUNC struct Picture * PIC_Get(mreg(__a0) struct Picture *Picture)
  42. {
  43.    if (Picture->Bitmap = Get(ID_BITMAP)) {
  44.       Picture->Bitmap->Parent = Picture;
  45.       Public->OpenCount++;
  46.       return(Picture);
  47.    }
  48.    else DPrintF("!Get:","Failed to obtain a Bitmap for this Picture.");
  49.    return(NULL);
  50. }
  51.  
  52. /************************************************************************************
  53. ** Action: Init()
  54. ** Object: Picture
  55. **
  56. ** Loads in a picture, automatically depacking it, assessing the info header and
  57. ** then copying it out to the bitmap.
  58. */
  59.  
  60. LIBFUNC LONG PIC_Init(mreg(__a0) struct Picture *Picture)
  61. {
  62.   struct File *File = NULL;
  63.   struct BMHD *BMHD = NULL;
  64.   LONG BodyPos  = NULL;
  65.   LONG CAMG     = NULL;
  66.   LONG *CMAP    = NULL;
  67.   LONG *Buffer  = NULL;
  68.   LONG error    = ERR_FAILED;
  69.   APTR FILBase  = GVBase->FileBase;    /* Seek() and OpenFile() */
  70.   WORD FreeFile = FALSE;
  71.   LONG FileSize;
  72.  
  73.   /* Open the file and allocate a read buffer.  Note that we check
  74.   ** if the Picture->Source is an initialised File, because we do
  75.   ** not want to open the file twice (illegal).
  76.   */
  77.  
  78.   if (((struct Head *)Picture->Source)->ID IS ID_FILE) {
  79.      if (CheckInit(Picture->Source) IS TRUE) {
  80.         File = Picture->Source;
  81.      }
  82.   }
  83.  
  84.   if (File IS NULL) {
  85.      if ((File = OpenFile(Picture->Source,FL_READ)) IS NULL) {
  86.         error = ErrCode(ERR_FILE);
  87.         goto exit;
  88.      }
  89.      else FreeFile = TRUE;
  90.   }
  91.  
  92.   Buffer = AllocMemBlock(BUFFERSIZE,MEM_DATA); /* Allocate a 4k buffer */
  93.  
  94.   /*** Check for the initial FORM/ILBM part ***/
  95.  
  96.   Seek(File, 0, POS_START); /* Required in case Picture->Source has been used */
  97.   Read(File, Buffer, 12);   /* [FORM] [Size] [ILBM] */
  98.   if ((Buffer[0] != CODE_FORM) OR (Buffer[2] != CODE_ILBM)) {
  99.      DPrintF("!Init:","This file does not start with a FORM/ILBM header.");
  100.      error = ERR_DATA;
  101.      goto exit;
  102.   }
  103.  
  104.   FileSize = Buffer[1];
  105.  
  106.   /*** Read each iff chunk in the file ***/
  107.  
  108.   while ((FileSize > 0) AND (BodyPos IS NULL)) {
  109.      if (Read(File,Buffer,8) != 8) { /* [CODE] [Size] */
  110.         DPrintF("!Query","I could not read the next chunk.");
  111.         goto exit;
  112.      }
  113.  
  114.      if (Buffer[1] & 0x00000001) Buffer[1] += 1;
  115.  
  116.      FileSize -= Buffer[1];
  117.  
  118.      if (Buffer[0] IS CODE_CMAP) {
  119.         DPrintF("3Init:","IFF CMAP header found.");
  120.         if (Buffer[1] > BUFFERSIZE) goto exit;
  121.         if (CMAP = AllocMemBlock(Buffer[1],MEM_DATA)) {
  122.            Read(File, CMAP, Buffer[1]);
  123.         }
  124.      }
  125.      else if (Buffer[0] IS CODE_BMHD) {
  126.         DPrintF("3Init:","IFF BMHD header found.");
  127.         if (Buffer[1] > BUFFERSIZE) goto exit;
  128.         if (BMHD = AllocMemBlock(Buffer[1],MEM_DATA)) {
  129.            if (Read(File, BMHD, Buffer[1]) != Buffer[1]) {
  130.               error = ErrCode(ERR_READ);
  131.               goto exit;
  132.            }
  133.         }
  134.         else {
  135.            error = ErrCode(ERR_MEMORY);
  136.            goto exit;
  137.         }
  138.      }
  139.      else if (Buffer[0] IS CODE_CAMG) {
  140.         DPrintF("3Init:","IFF CAMG header found.");
  141.         if (Buffer[1] > BUFFERSIZE) goto exit;
  142.         if (Read(File,Buffer,Buffer[1]) IS Buffer[1]) {
  143.            CAMG = Buffer[0];
  144.         }
  145.         else {
  146.            error = ErrCode(ERR_READ);
  147.            goto exit;
  148.         }
  149.      }
  150.      else if (Buffer[0] IS CODE_BODY) {
  151.         DPrintF("Init:","IFF BODY header found.");
  152.         BodyPos = File->BytePos;
  153.      }
  154.      else {
  155.         if (Seek(File, Buffer[1], POS_CURRENT) IS -1) { /* Skip to the next chunk */
  156.             DPrintF("!Init:","I could not seek to the correct file position.");
  157.             goto exit;
  158.         }
  159.      }
  160.   }
  161.  
  162.   if (BodyPos) {
  163.      /* Query the Picture and then initialise the Bitmap before
  164.      ** unpacking the file.
  165.      */
  166.  
  167.      if (Query(Picture) IS ERR_OK) {
  168.         Init(Picture->Bitmap,NULL);
  169.         Seek(File, BodyPos, POS_START);
  170.         error = UnpackPicture(Picture,BMHD,File,CMAP,CAMG);
  171.      }
  172.      else DPrintF("!Init:","Could not query picture information.");
  173.   }
  174.   else DPrintF("!Init:","Picture has no BODY chunk.");
  175.  
  176.   /*** Check for a Palette ***/
  177.  
  178.   if ((Picture->Bitmap->AmtColours <= 256) AND (Picture->Bitmap->Palette IS NULL)) {
  179.      DPrintF("!Init:","Warning - I could not obtain a palette from the file.");
  180.   }
  181.  
  182. exit:
  183.   if (Buffer) FreeMemBlock(Buffer);
  184.   if (BMHD)   FreeMemBlock(BMHD);
  185.   if (CMAP)   FreeMemBlock(CMAP);
  186.   if (FreeFile IS TRUE) Free(File);
  187.   return(error);
  188. }
  189.  
  190. /************************************************************************************
  191. ** Action: Load()
  192. ** Object: Picture
  193. **
  194. ** Loads in an object file that is known to be of the Picture class.  This action
  195. ** will get the palette of the Picture if there is one, and store the data in
  196. ** standard memory.
  197. **
  198. ** We use the File->Source rather than just the File, because we must assume
  199. ** that the File object will be freed by Load() and only the source will continue
  200. ** to be valid.
  201. */
  202.  
  203. LIBFUNC struct Picture * PIC_Load(mreg(__a0) struct File *File)
  204. {
  205.   struct Picture *Picture;
  206.  
  207.   Picture = InitTags(NULL,
  208.     TAGS_PICTURE, NULL,
  209.     PCA_Source,   File->Source,
  210.     TAGEND);
  211.  
  212.   return(Picture);
  213. }
  214.  
  215. /************************************************************************************
  216. ** Action: Query()
  217. ** Object: Picture
  218. **
  219. ** Gets picture information - width, height, amount of colors, planes etc.  It does
  220. ** not grab the data of the picture.
  221. */
  222.  
  223. LIBFUNC LONG PIC_Query(mreg(__a0) struct Picture *Picture)
  224. {
  225.   struct BMHD   *BMHD   = NULL;
  226.   struct File   *File   = NULL;
  227.   struct Bitmap *Bitmap;
  228.   LONG   error    = ERR_FAILED; /* The default code is for failure */
  229.   LONG   CAMG     = NULL;
  230.   LONG   *CMAP    = NULL;
  231.   LONG   CMAPSize = NULL;       /* Size of the CMAP array */
  232.   LONG   *Buffer  = NULL;
  233.   WORD   FreeFile = FALSE;
  234.   APTR   BLTBase  = GVBase->BlitterBase; /* GetBmpType() */
  235.   APTR   FILBase  = GVBase->FileBase;    /* Seek() and OpenFile() */
  236.   BYTE   *SrcPalette;
  237.   BYTE   *DestPalette;
  238.   LONG   i;
  239.   LONG   FileSize;
  240.  
  241.   DPrintF("~Query()","Picture: $%x", Picture);
  242.  
  243.   /*** Validation procedures ***/
  244.  
  245.   if ((Bitmap = Picture->Bitmap) IS NULL) {
  246.      DPrintF("!Query;","No Picture->Bitmap present.");
  247.      goto exit;
  248.   }
  249.  
  250.   /* Open the file and allocate a read buffer.  Note that we check
  251.   ** if the Picture->Source is an initialised File, because we do
  252.   ** not want to open the file twice (illegal).
  253.   */
  254.  
  255.   if (((struct Head *)Picture->Source)->ID IS ID_FILE) {
  256.      if (CheckInit(Picture->Source) IS TRUE) {
  257.         File = Picture->Source;
  258.      }
  259.   }
  260.  
  261.   if (File IS NULL) {
  262.      if ((File = OpenFile(Picture->Source,FL_READ)) IS NULL) {
  263.         error = ErrCode(ERR_FILE);
  264.         goto exit;
  265.      }
  266.      else FreeFile = TRUE;
  267.   }
  268.  
  269.   Buffer = AllocMemBlock(BUFFERSIZE,MEM_DATA); /* Allocate a 4k buffer */
  270.  
  271.   /*** Check for the initial FORM/ILBM part ***/
  272.  
  273.   Seek(File, 0, POS_START); /* Required in case Picture->Source has been used */
  274.   Read(File, Buffer, 12);   /* [FORM] [Size] [ILBM] */
  275.   if ((Buffer[0] != CODE_FORM) OR (Buffer[2] != CODE_ILBM)) {
  276.      DPrintF("!Query:","This file does not start with a FORM/ILBM header.");
  277.      error = ERR_DATA;
  278.      goto exit;
  279.   }
  280.  
  281.   FileSize = GetFSize(File);
  282.  
  283.   /*** Read each iff chunk in the file ***/
  284.  
  285.   while (File->BytePos < FileSize) {
  286.      if (Read(File,Buffer,8) != 8) { /* [CODE] [Size] */
  287.         DPrintF("!Query:","I could not read the next chunk.");
  288.         break;
  289.      }
  290.  
  291.      if (Buffer[1] & 0x00000001) Buffer[1] += 1;
  292.  
  293.      if (Buffer[0] IS CODE_CMAP) {
  294.         DPrintF("3Query:","IFF CMAP header found.");
  295.         if (Buffer[1] > BUFFERSIZE) goto exit;
  296.  
  297.         CMAPSize = Buffer[1]/3;
  298.         if (CMAP = AllocMemBlock(Buffer[1],MEM_DATA)) {
  299.            Read(File, CMAP, Buffer[1]);
  300.         }
  301.      }
  302.      else if (Buffer[0] IS CODE_BMHD) {
  303.         DPrintF("3Query:","IFF BMHD header found.");
  304.         if (Buffer[1] > BUFFERSIZE) goto exit;
  305.         if (BMHD = AllocMemBlock(Buffer[1],MEM_DATA)) {
  306.            if (Read(File, BMHD, Buffer[1]) != Buffer[1]) {
  307.               error = ErrCode(ERR_READ);
  308.               goto exit;
  309.            }
  310.         }
  311.         else {
  312.            error = ErrCode(ERR_MEMORY);
  313.            goto exit;
  314.         }
  315.      }
  316.      else if (Buffer[0] IS CODE_CAMG) {
  317.         DPrintF("3Query:","IFF CAMG header found.");
  318.         if (Buffer[1] > BUFFERSIZE) goto exit;
  319.         if (Read(File,Buffer,Buffer[1]) IS Buffer[1]) {
  320.            CAMG = Buffer[0];
  321.         }
  322.         else {
  323.            error = ErrCode(ERR_READ);
  324.            goto exit;
  325.         }
  326.      }
  327.      else {
  328.         DPrintF("3Query:","Unused chunk, skipping %ld bytes.",Buffer[1]);
  329.         if (Seek(File, Buffer[1], POS_CURRENT) IS -1) { /* Skip to the next chunk */
  330.             DPrintF("!Query:","I could not seek to the correct file position.");
  331.             goto exit;
  332.         }
  333.      }
  334.   }
  335.  
  336.   if (BMHD) {
  337.      if (Bitmap->AmtColours IS NULL) Bitmap->AmtColours = CMAPSize;
  338.      if (Bitmap->Height IS NULL)     Bitmap->Height     = BMHD->Height;
  339.      if (Bitmap->Planes IS NULL)     Bitmap->Planes     = BMHD->Depth;
  340.      if (Bitmap->Type IS NULL)       Bitmap->Type       = GetBmpType(); /* User preference */
  341.      if (Picture->ScrWidth IS NULL)  Picture->ScrWidth  = BMHD->ScrWidth;
  342.      if (Picture->ScrHeight IS NULL) Picture->ScrHeight = BMHD->ScrHeight;
  343.      if (Bitmap->Width IS NULL) {
  344.         Bitmap->Width     = BMHD->Width;
  345.         Bitmap->ByteWidth = NULL;        /* Let the Init(Bitmap) calculate it */
  346.      }
  347.   }
  348.  
  349.   if (CAMG) {
  350.      /* Note that if the programmer has preset a non-planar mode,
  351.      ** then we cannot set HAM or EHB bits (the picture will be
  352.      ** converted so special graphic flags do not apply).
  353.      */
  354.  
  355.      if ((Bitmap->Type IS ILBM) OR (Bitmap->Type IS PLANAR)) {
  356.         if ((Bitmap->Planes IS 6) OR (Bitmap->Planes IS 8)) {
  357.            if (CAMG & OSV_HAM) Picture->Bitmap->Flags |= BMF_HAM;
  358.            if (CAMG & OSV_EHB) Picture->Bitmap->Flags |= BMF_EXTRAHB;
  359.         }
  360.      }
  361.  
  362.      if (CAMG & OSV_LACED) Picture->ScrMode |= SM_LACED;
  363.      if (CAMG & OSV_HIRES) {
  364.         Picture->ScrMode |= SM_HIRES;
  365.      }
  366.      else Picture->ScrMode |= SM_LORES;
  367.   }
  368.  
  369.   /*** Generate Palette ***/
  370.  
  371.   if ((Bitmap->Palette IS NULL) AND (Bitmap->AmtColours <= 256) AND (CMAP)) {
  372.      if (Bitmap->Palette = AllocMemBlock((Bitmap->AmtColours * 4)+8,MEM_DATA)) {
  373.         Picture->prvPalette = Bitmap->Palette;
  374.         Bitmap->Palette[0]  = PALETTE_ARRAY;
  375.         Bitmap->Palette[1]  = Bitmap->AmtColours;
  376.         SrcPalette          = (BYTE *)CMAP;
  377.         DestPalette         = ((BYTE *)Bitmap->Palette)+8;
  378.         for (i=0; i < Bitmap->AmtColours; i++) {
  379.            DestPalette[1] = SrcPalette[0];
  380.            DestPalette[2] = SrcPalette[1];
  381.            DestPalette[3] = SrcPalette[2];
  382.            DestPalette += 4;
  383.            SrcPalette  += 3;
  384.         }
  385.      }
  386.      else {
  387.         error = ErrCode(ERR_MEMORY);
  388.         goto exit;
  389.      }
  390.   }
  391.  
  392.   /* Re/Initialise the Picture->Bitmap.  Note that because we are only
  393.   ** querying the Bitmap we set up a dummy data pointer.
  394.   */
  395.  
  396.   if (Query(Bitmap) != ERR_OK) {
  397.      DPrintF("!Query:","Failed to Query() the Bitmap.");
  398.      goto exit;
  399.   }
  400.  
  401.   error = ERR_OK;
  402.  
  403. exit:
  404.   if (Buffer) FreeMemBlock(Buffer);
  405.   if (BMHD)   FreeMemBlock(BMHD);
  406.   if (CMAP)   FreeMemBlock(CMAP);
  407.   if (FreeFile IS TRUE) Free(File);
  408.   StepBack();
  409.   return(error);
  410. }
  411.  
  412. /************************************************************************************
  413. ** Actions: File support.
  414. ** Object:  Picture
  415. ** Short:   These routines allow you to read/write to a Picture's Bitmap.
  416. */
  417.  
  418. LIBFUNC LONG PIC_Read(mreg(__a0) struct Picture *Picture, mreg(__a1) BYTE *Buffer, mreg(__d0) LONG Length) {
  419.   return(Read(Picture->Bitmap,Buffer,Length));
  420. }
  421.  
  422. LIBFUNC LONG PIC_Seek(mreg(__a0) struct Picture *Picture, mreg(__d0) LONG Offset, mreg(__d1) WORD Position) {
  423.   return(Seek(Picture->Bitmap,Offset,Position));
  424. }
  425.  
  426. LIBFUNC LONG PIC_Write(mreg(__a0) struct Picture *Picture, mreg(__a1) BYTE *Buffer, mreg(__d0) LONG Length) {
  427.   return(Write(Picture->Bitmap,Buffer,Length));
  428. }
  429.  
  430.